package org.pixelami.twisted.spread.flavors
{
	import org.pixelami.twisted.spread.errors.NoSuchMethodError;
	import org.pixelami.twisted.utils.PyTuple;
	
	public class Referencable extends Serializable
	{
		/*
		I am an object sent remotely as a direct reference.

	    When one of my subclasses is sent as an argument to or returned
	    from a remote method call, I will be serialized by default as a
	    direct reference.
	
	    This means that the peer will be able to call methods on me;
	    a method call xxx() from my peer will be resolved to methods
	    of the name remote_xxx.
	    */
	    
	    public var perspective:Object = null;
		
		public function Referencable()
		{
		}
		
    

	    public function  remoteMessageReceived(broker:Object, message:String, args:Array, kw:Object):Object
	    {
	        /*
	        A remote message has been received.  Dispatch it appropriately.
	
	        The default implementation is to dispatch to a method called
	        'remote_messagename' and call it with the same arguments.
	        */
	        var args:Array = broker.unserialize(args)
	        //var kw = broker.unserialize(kw)
	        //var method:Function = this["remote_" + message]
	        var method:Function = this.hasOwnProperty("remote_" + message) ? this["remote_" + message] : null;
	        if(method == null)
	        {
	            throw new NoSuchMethodError("No such method: remote_" + message);
	        }
	        try
	        {
	            var state:Object = method.apply(this,args);
	        }
	        catch(e:TypeError)
	        {
	            //log.msg("%s didn't accept %s and %s" % (method, args, kw));
	            
	            throw new Error(method+" didn't accept "+args);
	        }
	        return broker.serialize(state, this.perspective);
	    }
	
	    override public function jellyFor(jellier:*):Object
	    {
	        /*
	        (internal)
	
	        Return a tuple which will be used as the s-expression to
	        serialize this to a peer.
	        */
	        var regref:Object;
	        try
	        {
				regref = jellier.invoker.registerReference(this);
	        }
	        catch(e:Error)
	        {
	        	trace("regref error - "+e);
	        	throw(e);
	        }
	        return new PyTuple("remote", regref);
		}



	}
}